package p.ithorns.sample.module;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.ClassMetadata;
import org.springframework.util.ClassUtils;
import p.ithorns.sample.ModulePathConfig;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * ServletConfigScanner
 *
 * @author Ht.L
 * @date 2024-07-19 21:34
 * @since 1.0.0
 */
public class ModuleInterfaceScanner extends ClassPathScanningCandidateComponentProvider {

    final static Logger log = LoggerFactory.getLogger(ModuleInterfaceScanner.class);

    final BeanDefinitionRegistry registry;

    public ModuleInterfaceScanner(BeanDefinitionRegistry registry) {
        this.registry = registry;
        resetFilters(false);
        // 设置为 false 以避免扫描枚举和接口等
//        scanner.setResourcePattern("classpath*:**/*.class");
        // 添加类型过滤，只扫描实现了 MyConfig 接口的类
        addIncludeFilter((metadataReader, metadataReaderFactory) -> {
            // 检查当前类是否实现了 MyConfig 接口
            ClassMetadata metadata = metadataReader.getClassMetadata();
            boolean isCandidate = isImplement(metadata) && metadata.isConcrete() && !metadata.isInterface() && !metadata.isAbstract() && !metadata.isAnnotation();
            if (isCandidate) {
                log.info("ModulePath implement -> " + metadata + ":" + isCandidate);
            }
            return isCandidate;
        });
    }

    private boolean isImplement(String[] interfaceNames, Class<ModulePathConfig> targetInterface) {
        if (interfaceNames != null && targetInterface != null) {
            HashSet<String> names = new HashSet<>(Arrays.asList(interfaceNames));
            return names.contains(targetInterface.getCanonicalName());
        }
        return false;
    }

    private boolean isImplement(ClassMetadata metadata) {
        Class<?> aClass = null;
        try {
            aClass = Class.forName(metadata.getClassName());
        } catch (ClassNotFoundException e) {
            // log.warn(e.getMessage());
            return false;
        }
        Class<?>[] interfaces = ClassUtils.getAllInterfacesForClass(aClass);
        HashSet<Class<?>> names = new HashSet<>(Arrays.asList(interfaces));
        return names.contains(ModulePathConfig.class);
    }

    public Set<BeanDefinition> scan(String packageName) {
        // 扫描整个类路径
        return findCandidateComponents(packageName);
    }

    @Override
    protected BeanDefinitionRegistry getRegistry() {
        return registry;
    }
}